/**
 * 微信JSSDK测试和诊断工具
 * 用于帮助开发者测试和排查微信JSSDK初始化问题
 */

const wechatUtil = require('./wechatUtil');

/**
 * 显示JSSDK测试面板
 * 在页面中创建一个浮动面板，用于执行JSSDK测试
 */
function showTestPanel() {
  // 检查是否已存在测试面板
  if (document.getElementById('wx-jssdk-test-panel')) {
    return;
  }
  
  // 创建测试面板
  const panel = document.createElement('div');
  panel.id = 'wx-jssdk-test-panel';
  panel.style.cssText = `
    position: fixed;
    top: 10px;
    right: 10px;
    width: 300px;
    background: rgba(255, 255, 255, 0.95);
    border: 1px solid #ddd;
    border-radius: 8px;
    box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2);
    z-index: 9999;
    padding: 10px;
    font-size: 14px;
    line-height: 1.5;
    font-family: Arial, sans-serif;
    max-height: 90vh;
    overflow-y: auto;
  `;
  
  // 面板标题
  const title = document.createElement('div');
  title.innerHTML = '微信JSSDK测试工具';
  title.style.cssText = `
    font-size: 16px;
    font-weight: bold;
    margin-bottom: 10px;
    padding-bottom: 5px;
    border-bottom: 1px solid #eee;
    display: flex;
    justify-content: space-between;
    align-items: center;
  `;
  
  // 关闭按钮
  const closeBtn = document.createElement('button');
  closeBtn.innerHTML = '×';
  closeBtn.style.cssText = `
    background: none;
    border: none;
    font-size: 20px;
    cursor: pointer;
    color: #666;
  `;
  closeBtn.onclick = () => {
    document.body.removeChild(panel);
  };
  title.appendChild(closeBtn);
  panel.appendChild(title);
  
  // 信息显示区域
  const infoArea = document.createElement('div');
  infoArea.id = 'wx-test-info';
  infoArea.style.cssText = `
    margin-bottom: 10px;
    padding: 8px;
    background: #f8f8f8;
    border-radius: 4px;
    max-height: 200px;
    overflow-y: auto;
    font-family: monospace;
    white-space: pre-wrap;
    font-size: 12px;
  `;
  infoArea.innerHTML = '准备就绪，请选择测试操作...';
  panel.appendChild(infoArea);
  
  // 测试按钮组
  const buttonContainer = document.createElement('div');
  buttonContainer.style.cssText = `
    display: flex;
    flex-direction: column;
    gap: 8px;
  `;
  
  // 添加测试按钮
  const buttons = [
    { text: '检查环境', action: checkEnvironment },
    { text: '检查URL', action: checkUrl },
    { text: '验证签名', action: validateSignature },
    { text: '获取位置', action: testGetLocation },
    { text: '选择位置', action: testChooseLocation },
    { text: '运行完整诊断', action: runFullDiagnosis },
    { text: '清除缓存', action: clearCache }
  ];
  
  buttons.forEach(btn => {
    const button = document.createElement('button');
    button.innerHTML = btn.text;
    button.style.cssText = `
      padding: 8px 12px;
      background: #007bff;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      font-size: 13px;
      transition: background 0.2s;
    `;
    button.onmouseover = () => {
      button.style.background = '#0069d9';
    };
    button.onmouseout = () => {
      button.style.background = '#007bff';
    };
    button.onclick = () => {
      btn.action();
    };
    buttonContainer.appendChild(button);
  });
  
  panel.appendChild(buttonContainer);
  document.body.appendChild(panel);
  
  // 设置拖动功能
  makeDraggable(panel, title);
  
  console.log('微信JSSDK测试面板已显示');
  return panel;
}

/**
 * 使元素可拖动
 * @param {HTMLElement} element 要拖动的元素
 * @param {HTMLElement} handle 拖动的把手元素
 */
function makeDraggable(element, handle) {
  let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;
  
  handle.style.cursor = 'move';
  handle.onmousedown = dragMouseDown;
  
  function dragMouseDown(e) {
    e = e || window.event;
    e.preventDefault();
    // 获取鼠标位置
    pos3 = e.clientX;
    pos4 = e.clientY;
    document.onmouseup = closeDragElement;
    // 鼠标移动时调用函数
    document.onmousemove = elementDrag;
  }
  
  function elementDrag(e) {
    e = e || window.event;
    e.preventDefault();
    // 计算新位置
    pos1 = pos3 - e.clientX;
    pos2 = pos4 - e.clientY;
    pos3 = e.clientX;
    pos4 = e.clientY;
    // 设置元素新位置
    element.style.top = (element.offsetTop - pos2) + "px";
    element.style.left = (element.offsetLeft - pos1) + "px";
  }
  
  function closeDragElement() {
    // 停止移动
    document.onmouseup = null;
    document.onmousemove = null;
  }
}

/**
 * 更新信息显示区域
 * @param {String} message 要显示的信息
 * @param {Boolean} append 是否追加信息，默认false
 */
function updateInfo(message, append = false) {
  const infoArea = document.getElementById('wx-test-info');
  if (infoArea) {
    if (append) {
      infoArea.innerHTML += '<br>' + message;
    } else {
      infoArea.innerHTML = message;
    }
    // 滚动到底部
    infoArea.scrollTop = infoArea.scrollHeight;
  }
}

/**
 * 检查当前环境
 */
async function checkEnvironment() {
  updateInfo('检查微信环境...');
  
  try {
    // 检查用户代理
    const isWeixinBrowser = /MicroMessenger/i.test(navigator.userAgent);
    updateInfo(`当前浏览器: ${navigator.userAgent}`);
    updateInfo(`是否在微信中: ${isWeixinBrowser ? '是' : '否'}`, true);
    
    // 检查wx对象
    if (typeof wx !== 'undefined') {
      updateInfo(`wx对象存在: 是`, true);
    } else {
      updateInfo(`wx对象存在: 否 (未加载JSSDK脚本)`, true);
    }
    
    // 检查当前URL
    const currentUrl = location.href;
    const urlForSign = currentUrl.split('#')[0];
    updateInfo(`当前URL: ${currentUrl}`, true);
    updateInfo(`签名URL: ${urlForSign}`, true);
    
    // 检查开发环境
    const isDev = process.env.NODE_ENV === 'development';
    updateInfo(`开发环境: ${isDev ? '是' : '否'}`, true);
    
    // 显示wechatConfig信息
    updateInfo(`appId: ${wechatUtil.wechatConfig.appId}`, true);
    updateInfo(`debug模式: ${wechatUtil.wechatConfig.debug ? '开启' : '关闭'}`, true);
    
    updateInfo('环境检查完成', true);
  } catch (error) {
    updateInfo(`环境检查出错: ${error.message}`, true);
    console.error('环境检查出错:', error);
  }
}

/**
 * 检查URL是否符合要求
 */
function checkUrl() {
  updateInfo('检查URL...');
  
  try {
    const currentUrl = location.href;
    const urlForSign = currentUrl.split('#')[0];
    
    updateInfo(`完整URL: ${currentUrl}`);
    updateInfo(`签名URL: ${urlForSign}`, true);
    
    const urlCheck = wechatUtil.checkUrl(urlForSign);
    
    if (urlCheck.isValid) {
      updateInfo(`✓ URL有效: ${urlCheck.message}`, true);
    } else {
      updateInfo(`✗ URL无效: ${urlCheck.message}`, true);
      
      if (urlCheck.recommendedUrl) {
        updateInfo(`建议URL: ${urlCheck.recommendedUrl}`, true);
      }
    }
    
    // 检查URL长度
    updateInfo(`URL长度: ${urlForSign.length} 字符`, true);
    if (urlForSign.length > 512) {
      updateInfo(`⚠️ URL过长，可能导致问题`, true);
    }
    
    // 检查URL参数
    const hasParams = urlForSign.includes('?');
    updateInfo(`包含参数: ${hasParams ? '是' : '否'}`, true);
    
    // 检查是否为localhost
    const isLocalhost = urlForSign.includes('localhost') || urlForSign.includes('127.0.0.1');
    if (isLocalhost) {
      updateInfo(`⚠️ 使用localhost/127.0.0.1可能导致签名无效`, true);
    }
  } catch (error) {
    updateInfo(`URL检查出错: ${error.message}`, true);
    console.error('URL检查出错:', error);
  }
}

/**
 * 验证签名
 */
async function validateSignature() {
  updateInfo('验证签名...');
  
  try {
    const url = location.href.split('#')[0];
    updateInfo(`使用URL: ${url}`);
    
    // 生成配置
    updateInfo('正在生成配置...', true);
    const config = await wechatUtil.generateConfig(url, true);
    
    updateInfo('配置生成成功:', true);
    updateInfo(`appId: ${config.appId}`, true);
    updateInfo(`timestamp: ${config.timestamp}`, true);
    updateInfo(`nonceStr: ${config.nonceStr}`, true);
    updateInfo(`signature: ${config.signature}`, true);
    
    // 如果wx对象存在，尝试使用该配置
    if (typeof wx !== 'undefined') {
      updateInfo('正在验证配置...', true);
      
      // 暂存原有的错误回调
      const originalErrorCallback = window.wxJssdkErrorCallback;
      
      // 创建一个Promise来包装wx.config结果
      const result = await new Promise((resolve) => {
        // 设置错误回调
        window.wxJssdkErrorCallback = (error) => {
          resolve({ success: false, error });
        };
        
        // 设置成功回调
        wx.ready(() => {
          resolve({ success: true });
        });
        
        // 配置wx
        wx.config({
          debug: false, // 不在控制台输出调试信息
          appId: config.appId,
          timestamp: config.timestamp,
          nonceStr: config.nonceStr,
          signature: config.signature,
          jsApiList: ['getLocation', 'openLocation', 'chooseLocation']
        });
        
        // 设置错误事件
        wx.error((error) => {
          if (window.wxJssdkErrorCallback) {
            window.wxJssdkErrorCallback(error);
          }
        });
        
        // 5秒超时
        setTimeout(() => {
          resolve({ success: false, error: { errMsg: '超时，未收到回调' } });
        }, 5000);
      });
      
      // 恢复原有的错误回调
      window.wxJssdkErrorCallback = originalErrorCallback;
      
      if (result.success) {
        updateInfo('✓ 签名验证成功！配置有效', true);
      } else {
        updateInfo(`✗ 签名验证失败: ${result.error.errMsg}`, true);
        
        // 提供可能的解决方案
        if (result.error.errMsg && result.error.errMsg.includes('signature')) {
          updateInfo('可能原因:', true);
          updateInfo('1. URL不一致，请确保生成签名的URL和当前页面完全一致', true);
          updateInfo('2. 签名生成时间与使用时间差距过大', true);
          updateInfo('3. appId或appSecret配置错误', true);
          updateInfo('4. 公众号未正确配置JS接口域名', true);
        }
      }
    } else {
      updateInfo('⚠️ wx对象不存在，无法验证签名', true);
    }
  } catch (error) {
    updateInfo(`签名验证出错: ${error.message}`, true);
    console.error('签名验证出错:', error);
  }
}

/**
 * 测试获取位置功能
 */
function testGetLocation() {
  updateInfo('测试获取位置...');
  
  if (typeof wx === 'undefined') {
    updateInfo('⚠️ wx对象不存在，无法测试', true);
    return;
  }
  
  updateInfo('正在调用wx.getLocation...', true);
  
  wx.getLocation({
    type: 'gcj02',
    success: (res) => {
      updateInfo('✓ 获取位置成功:', true);
      updateInfo(`经度: ${res.longitude}`, true);
      updateInfo(`纬度: ${res.latitude}`, true);
      updateInfo(`精度: ${res.accuracy}米`, true);
      
      // 尝试使用openLocation显示位置
      updateInfo('是否在地图上显示位置?', true);
      
      const showBtn = document.createElement('button');
      showBtn.innerText = '在地图上显示';
      showBtn.style.marginTop = '5px';
      showBtn.style.marginRight = '5px';
      showBtn.style.padding = '3px 8px';
      showBtn.style.background = '#28a745';
      showBtn.style.color = 'white';
      showBtn.style.border = 'none';
      showBtn.style.borderRadius = '4px';
      showBtn.style.cursor = 'pointer';
      
      showBtn.onclick = () => {
        wx.openLocation({
          latitude: res.latitude,
          longitude: res.longitude,
          name: '当前位置',
          address: '位置信息由微信JSSDK提供',
          scale: 16
        });
        
        // 移除按钮
        if (showBtn.parentNode) {
          showBtn.parentNode.removeChild(showBtn);
        }
        if (cancelBtn.parentNode) {
          cancelBtn.parentNode.removeChild(cancelBtn);
        }
      };
      
      const cancelBtn = document.createElement('button');
      cancelBtn.innerText = '取消';
      cancelBtn.style.marginTop = '5px';
      cancelBtn.style.padding = '3px 8px';
      cancelBtn.style.background = '#dc3545';
      cancelBtn.style.color = 'white';
      cancelBtn.style.border = 'none';
      cancelBtn.style.borderRadius = '4px';
      cancelBtn.style.cursor = 'pointer';
      
      cancelBtn.onclick = () => {
        // 移除按钮
        if (showBtn.parentNode) {
          showBtn.parentNode.removeChild(showBtn);
        }
        if (cancelBtn.parentNode) {
          cancelBtn.parentNode.removeChild(cancelBtn);
        }
      };
      
      document.getElementById('wx-test-info').appendChild(showBtn);
      document.getElementById('wx-test-info').appendChild(cancelBtn);
    },
    fail: (error) => {
      updateInfo(`✗ 获取位置失败: ${error.errMsg}`, true);
      
      if (error.errMsg.includes('auth')) {
        updateInfo('可能是用户拒绝了位置权限，请确保用户已授权', true);
      }
    },
    complete: () => {
      updateInfo('位置获取请求完成', true);
    }
  });
}

/**
 * 测试选择位置功能
 */
function testChooseLocation() {
  updateInfo('测试选择位置...');
  
  if (typeof wx === 'undefined') {
    updateInfo('⚠️ wx对象不存在，无法测试', true);
    return;
  }
  
  updateInfo('正在调用wx.chooseLocation...', true);
  updateInfo('(请在弹出的地图中选择位置)', true);
  
  wx.chooseLocation({
    success: (res) => {
      updateInfo('✓ 选择位置成功:', true);
      updateInfo(`位置名称: ${res.name}`, true);
      updateInfo(`地址: ${res.address}`, true);
      updateInfo(`经度: ${res.longitude}`, true);
      updateInfo(`纬度: ${res.latitude}`, true);
    },
    fail: (error) => {
      updateInfo(`✗ 选择位置失败: ${error.errMsg}`, true);
      
      if (error.errMsg.includes('cancel')) {
        updateInfo('用户取消了选择', true);
      } else if (error.errMsg.includes('auth')) {
        updateInfo('可能是用户拒绝了位置权限，请确保用户已授权', true);
      }
    },
    complete: () => {
      updateInfo('位置选择请求完成', true);
    }
  });
}

/**
 * 运行完整诊断
 */
async function runFullDiagnosis() {
  updateInfo('运行完整诊断...');
  
  try {
    // 获取当前URL
    const url = location.href.split('#')[0];
    
    // 使用wechatUtil诊断工具
    updateInfo('正在执行JSSDK诊断...', true);
    const result = await wechatUtil.diagnose(url);
    
    // 显示诊断结果
    updateInfo(`诊断完成，状态: ${result.status}`, true);
    updateInfo(`消息: ${result.message}`, true);
    
    // 显示详细检查结果
    updateInfo('详细检查结果:', true);
    result.checks.forEach((check, index) => {
      const status = check.passed ? '✓' : '✗';
      updateInfo(`${status} ${check.name}: ${check.message}`, true);
    });
    
    // 显示生成的配置
    if (result.generatedConfig) {
      updateInfo('生成的配置:', true);
      updateInfo(`appId: ${result.generatedConfig.appId}`, true);
      updateInfo(`timestamp: ${result.generatedConfig.timestamp}`, true);
      updateInfo(`nonceStr: ${result.generatedConfig.nonceStr}`, true);
      updateInfo(`signature: ${result.generatedConfig.signature}`, true);
    }
    
    // 提供改进建议
    if (result.status !== '通过') {
      updateInfo('改进建议:', true);
      
      if (!result.checks.find(c => c.name === 'URL检查').passed) {
        updateInfo('1. 修正URL格式问题', true);
        if (result.fixedUrl) {
          updateInfo(`   推荐使用: ${result.fixedUrl}`, true);
        }
      }
      
      if (!result.checks.find(c => c.name === 'CryptoJS检查').passed) {
        updateInfo('2. 安装crypto-js依赖: npm install crypto-js', true);
      }
      
      if (!result.checks.find(c => c.name === 'AccessToken检查').passed) {
        updateInfo('3. 检查appId和appSecret配置是否正确', true);
      }
      
      updateInfo('4. 确保微信公众平台已配置JS接口安全域名', true);
      updateInfo('5. 检查服务器网络连接是否稳定', true);
    }
  } catch (error) {
    updateInfo(`诊断过程出错: ${error.message}`, true);
    console.error('诊断过程出错:', error);
  }
}

/**
 * 清除缓存
 */
function clearCache() {
  updateInfo('清除JSSDK缓存...');
  
  try {
    // 清除wechatUtil中的缓存
    wechatUtil.clearCache();
    updateInfo('✓ 工具类缓存已清除', true);
    
    // 尝试清除localStorage中可能的缓存
    const keysToRemove = [];
    for (let i = 0; i < localStorage.length; i++) {
      const key = localStorage.key(i);
      if (key && (key.includes('wx') || key.includes('jssdk') || 
          key.includes('token') || key.includes('ticket'))) {
        keysToRemove.push(key);
      }
    }
    
    if (keysToRemove.length > 0) {
      keysToRemove.forEach(key => localStorage.removeItem(key));
      updateInfo(`✓ 已清除localStorage中的 ${keysToRemove.length} 项缓存`, true);
    } else {
      updateInfo('localStorage中未找到相关缓存', true);
    }
    
    updateInfo('缓存清除完成', true);
    updateInfo('建议刷新页面以应用更改', true);
    
    // 添加刷新按钮
    const refreshBtn = document.createElement('button');
    refreshBtn.innerText = '刷新页面';
    refreshBtn.style.marginTop = '5px';
    refreshBtn.style.padding = '5px 10px';
    refreshBtn.style.background = '#28a745';
    refreshBtn.style.color = 'white';
    refreshBtn.style.border = 'none';
    refreshBtn.style.borderRadius = '4px';
    refreshBtn.style.cursor = 'pointer';
    
    refreshBtn.onclick = () => {
      location.reload();
    };
    
    document.getElementById('wx-test-info').appendChild(refreshBtn);
  } catch (error) {
    updateInfo(`清除缓存出错: ${error.message}`, true);
    console.error('清除缓存出错:', error);
  }
}

module.exports = {
  showTestPanel
}; 